package com.ncmmall.api.apis.mall;


import com.ncmmall.api.apis.service.Result;
import com.ncmmall.api.params.MerchantShoppingCartGoodsDTO;
import com.ncmmall.api.params.ShopCartDTO;
import com.ncmmall.api.security.Securitys;
import com.ncmmall.application.business.shoppingcart.ShoppingCartApplication;
import com.feijin.commons.exceptions.InterfaceException;
import com.feijin.commons.lang.ArithUtils;
import com.ncmmall.domain.business.goods.sku.GoodsSku;
import com.ncmmall.domain.business.goods.sku.QGoodsSku;
import com.ncmmall.domain.business.marketing.coupon.Coupon;
import com.ncmmall.domain.business.marketing.coupon.QCoupon;
import com.ncmmall.domain.business.marketing.seckill.SeckillSession;
import com.ncmmall.domain.business.order.OrderDetail;
import com.ncmmall.domain.business.shoppingcart.QShoppingCart;
import com.ncmmall.domain.business.shoppingcart.ShoppingCart;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author linxs
 * 购物车
 */
@RestController
@RequestMapping(value = "/shoppingcart")
@Component
public class ShoppingCartApi {

    private final Logger logger = LoggerFactory.getLogger(ShoppingCartApi.class);

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private ShoppingCartApplication shoppingCartApplication;

    @Value("${store.domain}")
    private String storeDomain;

    /**
     * 获取商家店铺所有的优惠券
     *
     * @param id 商家id
     */
    @RequestMapping(value = "/coupons", method = RequestMethod.GET)
    @ResponseBody
    public Result coupons(HttpServletRequest request, @RequestParam("id") long id) {
        Result result = new Result();
        try {
            UserCoupon userCoupon = new UserCoupon(new WebUser().setId(id), Securitys.user(request), queryChannelService);
            return result.ok().inject(ImmutableMap.of("coupons", userCoupon.getNotDraw(), "drawCoupons", userCoupon.getUsableDraw()));
        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            logger.error("[获取优惠券列表异常]", e);
            return result.fail().setMsg("网络连接失败");
        }
    }


    /**
     * 购物车商品数量
     */
    @RequestMapping(value = "/count", method = RequestMethod.GET)
    @ResponseBody
    public Result count(HttpServletRequest request) {
        Result result = new Result();
        try {

            WebUser member = Securitys.user(request);
            List<ShoppingCart> carts = queryChannelService.findAll(QShoppingCart.shoppingCart.member.eq(member), ShoppingCart.class);
            return result.ok().inject(ImmutableMap.of("count", carts.size()));

        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            logger.error("[获取购物车商品数量异常]", e);
            return result.fail().setMsg("网络连接失败");
        }

    }

    /**
     * 添加商品到购物车
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Result add(HttpServletRequest request, @RequestBody ShopCartDTO params) {

        Result result = new Result();

        try {
            WebUser member = Securitys.user(request);
            GoodsSku sku = queryChannelService.findOne(QGoodsSku.goodsSku.id.eq(params.getId()), GoodsSku.class);

            //秒杀已开始的商品
            if (sku.getGoods().getMarketingType() == 2 && sku.getGoods().getSeckillStatus() == 5 && sku.getGoods().getSeckillSession().getStatus() == 2) {

                SeckillSession seckillSession = sku.getGoods().getSeckillSession();
                Timestamp now = new Timestamp(System.currentTimeMillis());

                //如果商品还在秒杀当中
                if (Timestamp.valueOf(seckillSession.getSeckillTime() + " " + seckillSession.getSeckillBeginTime() + ":00").before(now) &&
                        Timestamp.valueOf(seckillSession.getSeckillTime() + " " + seckillSession.getSeckillEndTime() + ":00").after(now)) {

                    if (params.getQuantity() > sku.getSeckillLimit()) {
                        return result.fail().setMsg("秒杀商品不得大于限购数量" + sku.getSeckillLimit());
                    }

                    List<OrderDetail> orders = queryChannelService.findAll("select d from OrderDetail d where d.sku.id = :id and d.order.marketingType = 4  and d.order.status != 6 and d.seckillSession.id = :sid and d.order.member.id = :mid", ImmutableMap.of("id", sku.getId(), "sid", seckillSession.getId(), "mid", member.getId()), OrderDetail.class);

                    int quantitys = 0;

                    for (OrderDetail orderDetail : orders) {
                        quantitys += orderDetail.getQuantity();
                    }

                    if (quantitys + params.getQuantity() > sku.getSeckillLimit()) {
                        return result.fail().setMsg("该商品限购" + sku.getSeckillLimit() + "，您暂无购买资格");
                    }
                }
            }

            ShoppingCart shoppingCart = shoppingCartApplication.addGoodsToShoppingCart(member, sku, params.getQuantity());
            return result.ok().inject(shoppingCart);

        } catch (InterfaceException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            logger.error("[添加购物车异常]", e);
            return result.fail().setMsg("添加商品到购物车失败");
        }

    }


    /**
     * 修改商品在购物车中的数量
     */
    @RequestMapping(value = "/modify", method = RequestMethod.PUT)
    public Result modify(HttpServletRequest request, @RequestBody ShopCartDTO params) {

        Result result = new Result();

        try {

            QShoppingCart qShoppingCart = QShoppingCart.shoppingCart;
            WebUser member = Securitys.user(request);
            ShoppingCart cart = queryChannelService.findOne(qShoppingCart.member.eq(member).and(qShoppingCart.id.eq(params.getId())), ShoppingCart.class);

            //秒杀限购
            if (cart.getSku().getGoods().getMarketingType() == 2 && cart.getSku().getGoods().getSeckillStatus() == 5) {

                if (params.getQuantity() > cart.getSku().getSeckillStore()) {
                    return result.fail().setMsg("库存不足");
                }

                if (params.getQuantity() > cart.getSku().getSeckillLimit()) {
                    return result.fail().setMsg("秒杀商品不得大于限购数量" + cart.getSku().getSeckillLimit());
                }

                List<OrderDetail> orders = queryChannelService.findAll("select d from OrderDetail d where d.sku.id = :id and d.order.marketingType = 4  and d.order.status != 6 and d.seckillSession.id = :sid and d.order.member.id = :mid", ImmutableMap.of("id", cart.getSku().getId(), "sid", cart.getSku().getGoods().getSeckillSession().getId(), "mid", member.getId()), OrderDetail.class);

                int quantitys = 0;

                for (OrderDetail orderDetail : orders) {
                    quantitys += orderDetail.getQuantity();
                }

                if (quantitys + params.getQuantity() > cart.getSku().getSeckillLimit()) {
                    return result.fail().setMsg("该商品限购" + cart.getSku().getSeckillLimit() + "，您暂无购买资格");
                }
            }

            //特价
            if (cart.getSku().getGoods().getMarketingType() == 1 && cart.getSku().getGoods().getBargainStatus() == 5) {
                if (params.getQuantity() > cart.getSku().getBargainStore()) {
                    return result.fail().setMsg("库存不足");
                }
            }

            shoppingCartApplication.modifyQuantity(cart, params.getQuantity());

            return result.ok();

        } catch (Exception e) {
            logger.error("[修改购物车商品数据异常]", e);
            return result.fail().setMsg("修改数量失败");
        }

    }

    /**
     * 批量删除购物车内的商品
     */
    @RequestMapping(value = "/removes", method = RequestMethod.DELETE)
    @ResponseBody
    public Result removes(HttpServletRequest request, @RequestBody List<ShopCartDTO> params) {
        Result result = new Result();

        try {

            WebUser member = Securitys.user(request);

            List<Long> cardIds = params.parallelStream().map(ShopCartDTO::getId).collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(cardIds)) {
                QShoppingCart qShoppingCart = QShoppingCart.shoppingCart;
                shoppingCartApplication.removes(queryChannelService.findAll(qShoppingCart.member.eq(member).and(qShoppingCart.id.in(cardIds)), ShoppingCart.class));
            }

            return result.ok();

        } catch (Exception e) {
            logger.error("[批量删除购物车内商品异常]", e);
            return result.fail().setMsg("添加商品到购物车失败");
        }

    }

    /**
     * 购物车商品列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Result list(HttpServletRequest request) {
        Result result = new Result();
        try {

            WebUser member = Securitys.user(request);

            List<ShoppingCart> loseGoodsList = Lists.newArrayList();

            //获取去重后的商家ID
            List<ShoppingCart> shoppingCarts = queryChannelService.findAll(QShoppingCart.shoppingCart.member.eq(member), ShoppingCart.class);
            List<Long> merchantIds = Lists.newArrayList();
            for (ShoppingCart cart : shoppingCarts) {
                if (!merchantIds.contains(cart.getSku().getGoods().getMerchant().getId())) {
                    merchantIds.add(cart.getSku().getMerchant().getId());
                }
            }

            List<WebUser> merchants = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(merchantIds)) {
                merchants = queryChannelService.findAll(QWebUser.webUser.id.in(merchantIds), WebUser.class);
            }

            List<MerchantShoppingCartGoodsDTO> shopCartListDTOs = Lists.newArrayList();

            for (WebUser merchant : merchants) {
                MerchantShoppingCartGoodsDTO merchantItem = new MerchantShoppingCartGoodsDTO();
                merchantItem.setMerchantId(merchant.getId());
                merchantItem.setMerchantName(merchant.getShopName());

                List<Coupon> coupons = queryChannelService.findAll(QCoupon.coupon.merchant.id.eq(merchant.getId()).and(QCoupon.coupon.publishStatus.eq(2)), Coupon.class);
                if (!coupons.isEmpty()) {
                    merchantItem.setHaveCoupon(1);
                }

                List<ShoppingCart> items = Lists.newArrayList();
                for (ShoppingCart cart : shoppingCarts) {
                    if (cart.getSku().getGoods().getMerchant().getId() == merchant.getId()) {
                        cart.setGoodsImage(storeDomain + "/uploads/" + cart.getGoodsImage());
                        cart.setGoodsId(cart.getSku().getGoods().getId());
                        cart.setGoodsStatus(cart.getSku().getGoods().getStatus());

                        //特价活动商品
                        if (cart.getSku().getGoods().getMarketingType() == 1) {

                            if (cart.getSku().getGoods().getBargainStatus() == 5) {    //活动已开始
                                cart.setSubtotalPrice(ArithUtils.mul(cart.getSku().getBargainPrice(), cart.getQuantity()));
                            } else {
                                cart.setSubtotalPrice(ArithUtils.mul(cart.getSku().getPrice(), cart.getQuantity()));
                            }

                            cart.setBargainStatus(cart.getSku().getGoods().getBargainStatus());

                        }


                        //秒杀活动商品
                        if (cart.getSku().getGoods().getMarketingType() == 2) {

                            if (cart.getSku().getGoods().getSeckillStatus() == 5) {    //活动已开始
                                cart.setSubtotalPrice(ArithUtils.mul(cart.getSku().getSeckillPrice(), cart.getQuantity()));
                            } else {
                                cart.setSubtotalPrice(ArithUtils.mul(cart.getSku().getPrice(), cart.getQuantity()));
                            }

                            cart.setSeckillStatus(cart.getSku().getGoods().getSeckillStatus());

                        }

                        cart.setMarketingType(cart.getSku().getGoods().getMarketingType());

                        items.add(cart);

                        if (cart.getGoodsStatus() != 3) {
                            loseGoodsList.add(cart);
                        }

                        //预售跟拼团商品不支持购物车方式购买
                        if ((cart.getSku().getGoods().getMarketingType() == 3 && cart.getSku().getGoods().getPresellStatus() == 5) || (cart.getSku().getGoods().getMarketingType() == 4 && cart.getSku().getGoods().getGroupBookingStatus() == 5)) {
                            loseGoodsList.add(cart);
                        }

                    }

                }

                merchantItem.setGoodsList(items);
                shopCartListDTOs.add(merchantItem);

            }

            return result.ok().inject(ImmutableMap.of("merchants", shopCartListDTOs, "loseGoodsList", loseGoodsList));

        } catch (Exception e) {
            logger.error("[购物车商品列表异常]", e);
            return result.fail().setMsg("网络连接失败");
        }

    }


}
